import fs from 'fs';
import path from 'path';

import WEBHOOKS, { WebhookDefinition } from '@octokit/webhooks-examples';

const baseDir = path.join(__dirname, '../test/fixtures/generated');
fs.rmSync(baseDir, { recursive: true, force: true });
fs.mkdirSync(baseDir, { recursive: true });

const writedJsons = [] as [string, string][];
const typeSet = new Set<string>();

// pull_request_edited -> PullRequestEditedEvent
function transformType(type: string) {
  return (
    (type
      .split('_')
      .map((v) => v.charAt(0).toUpperCase() + v.slice(1))
      .join('') as string) + 'Event'
  );
}

function writeFile(name: string, type: string, data: any) {
  const _type = transformType(type);
  typeSet.add(_type);
  writedJsons.push([name, _type]);
  fs.writeFileSync(
    path.join(baseDir, name + '.json'),
    JSON.stringify(data, null, 2),
  );
}

for (const webhook of WEBHOOKS) {
  if (webhook.name === 'pull_request') {
    const pull_request = webhook as WebhookDefinition<'pull_request'>;
    pull_request.examples.forEach((v, i) => {
      if (
        v.action === 'edited' ||
        v.action === 'opened' ||
        v.action === 'closed'
      ) {
        writeFile(
          `pull_request_${v.pull_request.number}_${i}_${v.action}`,
          `pull_request_${v.action}`,
          v,
        );
      }
    });
  }
  if (webhook.name === 'pull_request_review') {
    const pull_request_review =
      webhook as WebhookDefinition<'pull_request_review'>;
    pull_request_review.examples.forEach((v, i) => {
      writeFile(
        `pull_request_review_${v.pull_request.number}_${i}_${v.action}_${v.review.state}`,
        'pull_request_review_' + v.action,
        v,
      );
    });
  }
  if (webhook.name === 'pull_request_review_comment') {
    const pull_request_review_comment =
      webhook as WebhookDefinition<'pull_request_review_comment'>;
    pull_request_review_comment.examples.forEach((v, i) => {
      if (
        v.action === 'edited' ||
        v.action === 'created' ||
        v.action === 'deleted'
      ) {
        writeFile(
          `pull_request_${v.pull_request.number}_review_comment_${i}_${v.action}`,
          'pull_request_review_comment_' + v.action,
          v,
        );
      }
    });
  }
  if (webhook.name === 'discussion') {
    const discussion = webhook as WebhookDefinition<'discussion'>;
    discussion.examples.forEach((v, i) => {
      if (v.discussion.number !== 90) {
        return;
      }
      writeFile(
        `discussion_${v.discussion.number}_${i}_${v.action}`,
        'discussion_' + v.action,
        v,
      );
    });
  }
  if (webhook.name === 'discussion_comment') {
    const discussion_comment =
      webhook as WebhookDefinition<'discussion_comment'>;
    discussion_comment.examples.forEach((v, i) => {
      if (v.discussion.number !== 90) {
        return;
      }

      writeFile(
        `discussion_comment_${v.discussion.number}_${i}_${v.action}`,
        'discussion_comment_' + v.action,
        v,
      );
    });
  }
  if (webhook.name === 'commit_comment') {
    const commit_comment = webhook as WebhookDefinition<'commit_comment'>;
    commit_comment.examples.forEach((v, i) => {
      if (i > 0) {
        return;
      }
      writeFile(
        `commit_comment_${v.comment.commit_id.slice(0, 6)}_${i}_${v.action}`,
        'commit_comment_' + v.action,
        v,
      );
    });
  }
  if (webhook.name === 'issue_comment') {
    const issue_comment = webhook as WebhookDefinition<'issue_comment'>;
    issue_comment.examples.forEach((v, i) => {
      if (i > 0) {
        return;
      }
      writeFile(
        `issue_comment_${v.issue.number}_${i}_${v.action}`,
        'issue_comment_' + v.action,
        v,
      );
    });
  }
}

const tsContent = `
// This file is generated by scripts/extract-webhook-example.ts

import { ${Array.from(typeSet).join(',')} } from '@octokit/webhooks-types';


${writedJsons
  .map(([v]) => {
    return `import _${v} from './${v}.json';`;
  })
  .join('\n')}

${writedJsons
  .map(([v, type]) => `export const ${v} = _${v} as unknown as ${type};`)
  .join('\n')}

`;

fs.writeFileSync(path.join(baseDir, 'index.ts'), tsContent);
